#include <iostream>
#include <vector>
#include <functional>
#include<unordered_map>
#include<cstdint>
#include<memory>
#include<unistd.h>



using TaskFunc=std::function<void()>;//任务函数类型
using ReleaseFunc=std::function<void()>;
class TimerTask//定时器任务类
{
private:
    bool _is_deleted=false;//是否已经被删除
    uint64_t _id;//标识任务，方便查找
    uint32_t _timeout;//超时时间，每隔多长时间算一次超时
    TaskFunc _task_cb;//定时器对象要执行的定时任务
    ReleaseFunc _release;//用于删除TimeWheel保存的weakptr定时器对象
public:
    TimerTask(uint64_t id,uint32_t delay,const TaskFunc& task_cb)
    :_id(id),_timeout(delay),_task_cb(task_cb),_release(nullptr),_is_deleted(false){}
    //在析构时执行定时任务
    ~TimerTask(){
      if(!_is_deleted)
      _task_cb();
      _release();
    }
    //取消定时器任务
    void Cancel(){_is_deleted=true;}
    uint32_t DelayTime(){return _timeout;}//获取定时器的延迟时间
    void SetRelease(const ReleaseFunc& release){_release=release;}//设置释放函数
};

class TimeWheel{//时间轮类
  private:
    int _tick;//当前时间轮走到哪里了--秒针
    int _capacity;//时间轮的容量--最大延迟时间
    using WeakTask=std::weak_ptr<TimerTask>;//弱智能指针，指向定时器任务
    using PtrTask=std::shared_ptr<TimerTask>;//智能指针，指向定时器任务
    std::vector<std::vector<PtrTask>> _wheel;
    std::unordered_map<uint64_t,WeakTask> _timers;
    void RemoveTimer(uint64_t id){
        auto it=_timers.find(id);
        if(it!=_timers.end()){
          _timers.erase(it);
      }
    }
    int timefd;
  public:
    TimeWheel():_capacity(1024),_tick(0),_wheel(_capacity){}
    //添加定时任务
    void TimerAdd(uint64_t id,uint32_t delay,const TaskFunc& task_cb){
        auto task=std::make_shared<TimerTask>(id,delay,task_cb);
        task->SetRelease(std::bind(&TimeWheel::RemoveTimer,this,id));
        _timers[id]=WeakTask(task);
          _wheel[(delay+_tick)%_capacity].push_back(task);
    }
    void TimerRefresh(uint64_t id){
        auto it=_timers.find(id);
        if(it!=_timers.end()){
          PtrTask pt=it->second.lock();
          uint32_t delay=pt->DelayTime();
          _wheel[(delay+_tick)%_capacity].push_back(pt);
      }
    }
    void TimerCancel(uint64_t id){
        auto it=_timers.find(id);
        if(it!=_timers.end()){
          PtrTask pt=it->second.lock();
          if(pt)
            pt->Cancel();
        }
    }
    //这个函数应该每秒执行一次，
    void RunTimerTask(){
        _tick=(_tick+1)%_capacity;
        //clear会清理数组中的shared_ptr资源
        _wheel[_tick].clear();
    }
};
class Test{
  public:
  Test(){std::cout<<"Test"<<std::endl;}
  ~Test(){std::cout<<"~Test"<<std::endl;}
};
void DelTest(Test* t){delete t;}


int main(){
  TimeWheel tw;
  Test* t=new Test();
  tw.TimerAdd(1,5,std::bind(DelTest,t));
  for(int i=0;i<5;i++){
     tw.TimerRefresh(1);
    tw.RunTimerTask();
    std::cout<<"刷新了一次定时任务，时间过了一秒"<<"\n";
    sleep(1);
  }
  tw.TimerCancel(1);
  while(true){
   
    tw.RunTimerTask();
    std::cout<<"不刷新了定时任务，时间过了一秒"<<"\n";
    sleep(1);
  }
 
  return 0;
}